package com.uniflow.controller;

import com.uniflow.common.Result;
import com.uniflow.common.ResultCode;
import com.uniflow.entity.User;
import com.uniflow.security.CustomUserDetails;
import com.uniflow.service.AuthService;
import com.uniflow.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 */
@RestController
@RequestMapping("/api/v1/auth")
@Validated
@Api(tags = "认证授权")
public class AuthController {
    
    @Autowired
    private AuthService authService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@Valid @RequestBody LoginRequest request) {
        try {
            Map<String, Object> result = authService.login(request.getUsername(), request.getPassword());
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.LOGIN_FAILED, e.getMessage());
        }
    }
    
    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result<Map<String, Object>> register(@Valid @RequestBody RegisterRequest request) {
        try {
            Map<String, Object> result = authService.register(request);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.REGISTER_FAILED, e.getMessage());
        }
    }
    
    /**
     * 刷新令牌
     */
    @PostMapping("/refresh")
    public Result<Map<String, Object>> refresh(@Valid @RequestBody RefreshTokenRequest request) {
        try {
            String refreshToken = request.getRefreshToken();
            
            // 验证刷新令牌
            if (!jwtUtil.validateTokenFormat(refreshToken) || !jwtUtil.isRefreshToken(refreshToken)) {
                return Result.error(ResultCode.TOKEN_INVALID);
            }
            
            // 生成新的访问令牌
            Map<String, Object> result = authService.refreshToken(refreshToken);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.TOKEN_REFRESH_FAILED, e.getMessage());
        }
    }
    
    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public Result<Void> logout(HttpServletRequest request) {
        try {
            // 获取当前用户
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
                CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
                
                // 执行登出逻辑（如果需要的话，可以将token加入黑名单）
                authService.logout(userDetails.getId());
            }
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.LOGOUT_FAILED, e.getMessage());
        }
    }
    
    /**
     * 获取当前用户信息
     */
    @GetMapping("/me")
    public Result<Map<String, Object>> getCurrentUser() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
                CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
                
                Map<String, Object> userInfo = new HashMap<>();
                userInfo.put("id", userDetails.getId());
                userInfo.put("username", userDetails.getUsername());
                userInfo.put("email", userDetails.getEmail());
                userInfo.put("displayName", userDetails.getDisplayName());
                userInfo.put("orgId", userDetails.getOrgId());
                userInfo.put("roles", userDetails.getRoleNames());
                userInfo.put("permissions", userDetails.getPermissions());
                
                return Result.success(userInfo);
            }
            
            return Result.error(ResultCode.UNAUTHORIZED);
        } catch (Exception e) {
            return Result.error(ResultCode.USER_INFO_FAILED, e.getMessage());
        }
    }
    
    /**
     * 修改密码
     */
    @PostMapping("/change-password")
    public Result<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
                CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
                
                authService.changePassword(userDetails.getId(), request.getOldPassword(), request.getNewPassword());
                return Result.success();
            }
            
            return Result.error(ResultCode.UNAUTHORIZED);
        } catch (Exception e) {
            return Result.error(ResultCode.PASSWORD_CHANGE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 验证令牌
     */
    @PostMapping("/validate")
    public Result<Map<String, Object>> validateToken(@Valid @RequestBody ValidateTokenRequest request) {
        try {
            String token = request.getToken();
            boolean isValid = jwtUtil.validateTokenFormat(token);
            
            Map<String, Object> result = new HashMap<>();
            result.put("valid", isValid);
            
            if (isValid) {
                result.put("username", jwtUtil.getUsernameFromToken(token));
                result.put("userId", jwtUtil.getUserIdFromToken(token));
                result.put("orgId", jwtUtil.getOrgIdFromToken(token));
                result.put("tokenType", jwtUtil.getTokenTypeFromToken(token));
                result.put("remainingTime", jwtUtil.getTokenRemainingTime(token));
            }
            
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.TOKEN_VALIDATION_FAILED, e.getMessage());
        }
    }
    
    // 内部类：请求对象
    
    public static class LoginRequest {
        @NotBlank(message = "用户名不能为空")
        private String username;
        
        @NotBlank(message = "密码不能为空")
        private String password;
        
        // getters and setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
    
    public static class RegisterRequest {
        @NotBlank(message = "用户名不能为空")
        private String username;
        
        @NotBlank(message = "邮箱不能为空")
        private String email;
        
        @NotBlank(message = "密码不能为空")
        private String password;
        
        @NotBlank(message = "显示名称不能为空")
        private String displayName;
        
        private String phone;
        private String orgId;
        
        // getters and setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDisplayName() { return displayName; }
        public void setDisplayName(String displayName) { this.displayName = displayName; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getOrgId() { return orgId; }
        public void setOrgId(String orgId) { this.orgId = orgId; }
    }
    
    public static class RefreshTokenRequest {
        @NotBlank(message = "刷新令牌不能为空")
        private String refreshToken;
        
        public String getRefreshToken() { return refreshToken; }
        public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; }
    }
    
    public static class ChangePasswordRequest {
        @NotBlank(message = "原密码不能为空")
        private String oldPassword;
        
        @NotBlank(message = "新密码不能为空")
        private String newPassword;
        
        public String getOldPassword() { return oldPassword; }
        public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }
    
    public static class ValidateTokenRequest {
        @NotBlank(message = "令牌不能为空")
        private String token;
        
        public String getToken() { return token; }
        public void setToken(String token) { this.token = token; }
    }
}